package com.eobjectsoft.etranslator.engine;

import com.eobjectsoft.etranslator.utils.LOG;
import java.net.URL;
import java.util.*;


public class TranslateEngine
{
	/**
	 * url for google translation service
	 */
	private static final String BASE_URL = "http://www.google.com/translate_t?";
    private TranslateMode transMode;
    protected static TranslateEngine instance = null;
    protected static SortedSet<String> supportedLans = null;
    protected static SortedMap<String, List<String>> transModeTab = null;


    protected TranslateEngine()
    {
        initTransModeTab();
    }

    public static TranslateEngine getInstance()
    {
        if(instance == null)
            instance = new TranslateEngine();
        return instance;
    }

    public Set<String> getFromLans()
    {
        return transModeTab.keySet();
    }

    public List<String> getToLans(String fromLanguage)
    {
        return (List<String>)transModeTab.get(fromLanguage);
    }

    public String[] getAllSupportedLan()
    {
        return (String[])supportedLans.toArray(new String[0]);
    }

    private void initTransModeTab()
    {
        transModeTab = new TreeMap<String, List<String>>();
        supportedLans = new TreeSet<String>();
        for(int i = 0; i < TranslateMode.modes.length; i++)
        {
            TranslateMode mode = TranslateMode.modes[i];
            String from = mode.getFromLanguage();
            String to = mode.getTargetLanguage();
            if(!supportedLans.contains(to))
                supportedLans.add(to);
            if(!transModeTab.containsKey(from))
            {
                ArrayList<String> targets = new ArrayList<String>();
                targets.add(to);
                transModeTab.put(from, targets);
            } else
            {
                ArrayList<String> targets = (ArrayList<String>)transModeTab.get(from);
                targets.add(to);
            }
        }

    }

    public void setTranslateMode(TranslateMode mode)
    {
        transMode = mode;
    }

    /**
     * translate the input string to target language
     * @param input
     * @return
     * @throws Exception
     */
    public synchronized String translate(String input)
        throws Exception
    {
        if(transMode == null)
            return "";
        //ignore space
        input = input.trim();
        byte resultBytes[];
        LOG.debug("input:" + input);
        URL url = createURL(input);
        LOG.debug("url:" + url.toExternalForm());
        resultBytes = TranslateUtils.getUrlResult(url);
        if(resultBytes != null && resultBytes.length != 0) {
        	return getContent(new String(resultBytes, TranslateUtils.DEFAULT_CHARTSET));	
        } 
        LOG.error("error during get result for input:" + input, null);
        return input;
    }

    /**
     * create the translate request URL
     * @param inputText
     * @return
     */
    private URL createURL(String inputText)
    {
    	try {
			if (inputText.indexOf(" ") > 0)
				inputText = inputText.replaceAll(" ", "%20");
			return new URL(BASE_URL + "langpair="
					+ transMode.toString() + "&text=" + inputText);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
    }

    /**
     * decode the response html content
     * @param htmltext
     * @return
     * @throws Exception
     */
    private static String getContent(String htmltext)
        throws Exception
    {
        String ss = "<div id=result_box dir=\"ltr\">";
        String se = "</div>";
        int ssidx = htmltext.indexOf(ss);
        int seidx = htmltext.indexOf(se, ssidx);
        if(ssidx < 0 || seidx < 0)
        {
            LOG.error("error parsing result from http response:" + htmltext, null);
            return null;
        }
        String restr = htmltext.substring(ssidx + ss.length(), seidx);
        LOG.debug("resut:" + restr);
        if(LOG.isDebugMode())
            LOG.debug("result hex:" + TranslateUtils.toHexString(restr.getBytes(TranslateUtils.DEFAULT_CHARTSET)));
        return restr;
    }

    
}
